package com.banggood.upms.web;

import com.banggood.silk.web.api.exception.SkbException;
import com.banggood.upms.bean.exception.ExceptionEnum;
import com.banggood.upms.bean.po.Tree;
import com.banggood.upms.bean.po.TreePermission;
import com.banggood.upms.bean.vo.TreePermissionVo;
import com.banggood.upms.bean.vo.search.TreePermissionSearchCriteria;
import com.banggood.upms.bean.vo.validation.AdjustGroup;
import com.banggood.upms.bean.vo.validation.SearchGroup;
import com.banggood.upms.service.TreePermissionService;
import com.banggood.upms.service.TreeService;
import com.banggood.upms.converter.TreePermConverter;
import io.swagger.annotations.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

/**
 * @author XuChuangFeng
 */
@RequestMapping("/tree-perm")
@RestController
@Api(value = "树与权限管理，树节点分配权限，树节点权限检索。")
public class TreePermController {

    protected final Log logger = LogFactory.getLog(getClass());
    @Autowired
    private TreePermissionService treePermissionService;
    @Autowired
    private TreeService treeService;
    @Autowired
    private TreePermConverter treePermConverter;

    /**
     * 树跟权限的分配映射（树包括角色跟部门）
     * @param vo
     * @return
     */
    @RequestMapping(value = "/adjust", method = RequestMethod.POST)
    @ApiOperation(value = "树节点权限分配调整", notes = "必须指定系统ID。")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "systemId", value = "系统ID，不指定抛异常", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "treeId", value = "要分配权限的树节点ID", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "newPermIds", value = "该树节点最新的权限ID列表，不传入的删除全部已分配的权限", required = true, paramType = "query", dataType = "String"),
    })
    @ApiResponses({
            @ApiResponse(code = 1001, message = "必须指定系统进行权限分配!"),
            @ApiResponse(code = 2008, message = "树节点不存在!"),
            @ApiResponse(code = 2009, message = "必须指定树节点ID!")
    })
    public String assignPerm(@Validated({AdjustGroup.class}) TreePermissionVo vo) throws Exception {
        // 需要传入系统ID，否则其他系统的数据将会被删除
        if(StringUtils.isEmpty(vo.getSystemId())) {
            throw new SkbException(ExceptionEnum.SYSTEM_ID_CANT_BE_NULL.getCode(), ExceptionEnum.SYSTEM_ID_CANT_BE_NULL.getMessage());
        }
        if(StringUtils.isEmpty(vo.getTreeId())) {
            throw new SkbException(ExceptionEnum.MISSING_TREE_ID.getCode(), ExceptionEnum.MISSING_TREE_ID.getMessage());
        }
        Tree tree = treeService.selectByPrimaryKey(vo.getTreeId());
        if(tree == null) {
            throw new SkbException(ExceptionEnum.NODE_NOT_EXISTS.getCode(), ExceptionEnum.NODE_NOT_EXISTS.getMessage());
        }
        /**
         * TODO 要判断传入的权限是否属于这个系统
         * #1, 查看之前是否为这个树节点分配过权限，如果没有就直接将此次添加的全部新增，返回
         * #2, 分配过权限的话，要做比较，分配前A跟分配后B的集合的并集C不做任何操作，C在A中的绝对补集做删除操作，C在B中的绝对补集做新增操作。
         * #3, 逻辑跟用户分配树一样
         */
        logger.debug("本次操作的树节点主键：" + vo.getTreeId());
        String brief;
        // 前端没有传入任何的分配ID，newTreeIds是空，直接删除所有已分配的
        // TODO 传入系统ID，则仅仅是删除这个系统下面的分配
        if(CollectionUtils.isEmpty(vo.getNewPermIds())) {
            brief = treePermissionService.deleteAll(vo);
        } else {
            // #1, 根据树节点的ID找出这个节点已经分配过的权限
            TreePermissionSearchCriteria searchCriteria = new TreePermissionSearchCriteria();
            searchCriteria.setSystemId(vo.getSystemId());
            searchCriteria.setTreeId(vo.getTreeId());
            List<TreePermission> preAdjustTreePerms = treePermissionService.selectByTreeIdAndSystemId(searchCriteria);
            if(CollectionUtils.isEmpty(preAdjustTreePerms)) {
                brief =  treePermissionService.insertTreePerms(treePermConverter.transferToPersistentList(vo));
            } else {
                // #2
                List<String> idsForRemove = new ArrayList<>();
                List<TreePermission> objForInsert = new ArrayList<>();
                // 初始化待删除列表跟带添加列表
                treePermConverter.prepareAdjustElements(vo, preAdjustTreePerms, idsForRemove, objForInsert);
                brief =  treePermissionService.adjustTreePerms(objForInsert, idsForRemove);
            }
        }
        return brief;
    }

    /**
     *
     * @param vo
     * @return 树节点在某个系统下面权限的分配情况
     */
    @RequestMapping(value = "/search", method = RequestMethod.POST)
    @ApiOperation(value = "树节点分配的权限数据搜索，指定树节点，返回该树节点分配的权限", notes = "POST请求")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "treeId", value = "树节点ID", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "systemId", value = "系统ID，不传的话默认返回在所有系统上面分配的权限", required = false, paramType = "query", dataType = "String"),
    })
    public List<TreePermission> selectUserTrees(@Validated({SearchGroup.class}) TreePermissionSearchCriteria vo){
        List<TreePermission> treePerms = treePermissionService.selectByTreeIdAndSystemId(vo);
        return treePerms;
    }
}